package icantalk.voip;

import java.io.IOException;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.sampled.LineUnavailableException;
import javax.swing.JOptionPane;
import org.xiph.speex.SpeexDecoder;
import org.xiph.speex.SpeexEncoder;

/**
 * B2B Phone project
 *
 * @author Antonín Brettšnajdr
 */

public class VoipHandler {

   // private static javax.swing.JLabel statusLabelStatic;

//    static void setText(String string) {
//        if (statusLabelStatic != null) {
//            statusLabelStatic.setText(string);
//        }
//    }

    private DatagramSocket 		socket;
    private SoundIO 			snd;
    private SpeexEncoder 		speexEnc;
    private SpeexDecoder 		speexDec;
    private InetSocketAddress 	address;
    
    private receiveThread 	receiveThread;
    private sendThread 		sendThread;
    


	private boolean isActive;
    

    public VoipHandler() {
    	isActive = false;
	}
    

    public void ConnectTo (final String ip)
    {
    	 new Thread(new Runnable() {

             @Override
             public void run() {
                 connect(ip);
     
                 snd = new SoundIO();
                 try {
                     snd.setUpMicrophone();
                     snd.setUpPlayback();
                     snd.startRecording();
                     snd.startPlaying();
                 } catch (LineUnavailableException ex) {
                     JOptionPane.showMessageDialog(null, "Cannot initialize sound card. Device is used by another application?");
                     System.exit(0);
                 }

                 runThreads();

             }

             private void runThreads() {
                 //Threads for receiving and sending
             	receiveThread 	= new receiveThread(socket,snd);
             	sendThread 		= new sendThread(socket,snd,address);
             	
                 //receiving
             	new Thread(receiveThread).start();
                 //sending
             	new Thread(sendThread).start();
               
             }
         }).start();
    }

	private void connect(String ip) {
        try {
        	isActive = true;
            UDPTunneler tun = new UDPTunneler(65000, ip, 65000);
            tun.createTunnel();
            socket = tun.socket;
            address = new InetSocketAddress(ip, 65000);
        } catch (IOException ex) {
            Logger.getLogger(main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
     
     public void hangup()
     {
    	 isActive = false;
    	 
    	 receiveThread.stopRunning();
    	 sendThread.stopRunning();
    	 snd.stopRecording();
    	 snd.stopPlaying();
    	 snd.freeResources();
    	 
    	 if ( socket.isConnected() )
    		 socket.disconnect();
    	 
    	 if ( !socket.isClosed() )
    		 socket.close();
    	 
    	 socket = null;
    	 address = null;
    	 
     }

     private byte[] encodeWithSPEEX(byte[] buff) {

        if (speexEnc == null) {
            speexEnc = new SpeexEncoder();
            speexEnc.init(1, 3, 8000, 1);
        }

        speexEnc.processData(buff, 0, buff.length);

        byte[] out = new byte[speexEnc.getProcessedDataByteSize()];
        speexEnc.getProcessedData(out, 0);

        return out;
    }
     
    public boolean isActive() {
 		return isActive;
 	}

}
